package com.ia.bo;

import com.ia.sd.*;

public class calcularCamino {

    private final int posO, posD, lineaO, lineaD;
    private pila abierta;
    private pila cerrada;
    private mapaMetro mapa = mapaMetro.getMapaMetro();

    public calcularCamino(int posO, int posD, int lineaO, int lineaD) {
        this.posO = posO;
        this.posD = posD;
        this.lineaO = lineaO;
        this.lineaD = lineaD;
        this.abierta = new pila();
        this.cerrada = new pila();
    }

    public pila calcularCamino(mapaMetro mapa) {
        pila respuesta;
        boolean meta = false;
        nodo estacion, aux, aux3;
        int[][] adyacentes;
        float coste, costeAnt;
        
        costeAnt = mapa.obtenerH(posO, posD, lineaO, lineaD);
        coste = costeAnt;
        abierta.apilarOrdenado(new nodo(posO, lineaO, coste));
        while ((!abierta.vacia()) && (!meta)) {
            estacion = abierta.desapilar();
            if (this.mapa.igual(estacion.getPos(), posD, estacion.getLinea(), lineaD)) {
                meta = true;
            } else {
                adyacentes = mapa.obtenerAdyacentes(estacion.getPos(), estacion.getLinea());
                for (int i = 0; i < adyacentes.length; i++) {
                    aux = new nodo(adyacentes[i][0], adyacentes[i][1]);
                    if (cerrada.esta(aux) == null) {
                        coste = costeAnt;
                        coste += (adyacentes[i][0] > estacion.getPos()) ? mapa.getG()[estacion.getLinea()][estacion.getPos()] : mapa.getG()[adyacentes[i][1]][adyacentes[i][0]];
                        coste += mapa.obtenerH(adyacentes[i][0], this.posD, adyacentes[i][1], this.lineaD);
                        coste += (adyacentes[i][1] != estacion.getLinea()) ? mapa.obtenerCosteTrasbordo(estacion.getPos(), estacion.getLinea()) : 0;
                        aux.setCoste(coste);
                        aux.setPuntero(estacion.getPos(), estacion.getLinea());
                        aux3 = abierta.esta(aux);
                        if (aux3 != null) {
                            if (aux3.getCoste() > aux.getCoste()) {
                                abierta.intercambiarDatos(aux);
                            }
                        } else {
                            abierta.apilarOrdenado(aux);
                        }
                    }
                }
            }
            cerrada.apilar(estacion);
        }
        if (!meta) {
            respuesta = null;
        } else {
            //respuesta = new String[]{"Estaciones a recorrer:"};
            int numTransbordos = 0;
            nodo aux2 = null;
            pila auxP = new pila();
            aux = cerrada.desapilar();
            auxP.apilar(aux);
            while (!cerrada.vacia()) {
                aux2 = cerrada.desapilar();
                int[] p = aux.getPuntero();
                if ((p[0] == aux2.getPos()) && (p[1] == aux2.getLinea())) {
                    auxP.apilar(aux2);
                    aux = aux2;
                }
            }
            respuesta = auxP;
//            aux = auxP.desapilar();
//            respuesta = new String[]{"Recorrer por la línea " + aux.getLinea() + ": " + mapa.getLineas()[aux.getLinea()][aux.getPos()]};
//            while (!auxP.vacia()) {
//                aux2 = auxP.desapilar();
//                if (aux.getLinea() == aux2.getLinea()) {
//                    respuesta[0] = respuesta[0].concat(" - " + mapa.getLineas()[aux2.getLinea()][aux2.getPos()]);
//                } else {
//                    
//                }
//                aux = aux2;
//            }
        }
        return respuesta;
    }
}
